package myJs.user.soft.fileSelect

import myJs.Implicits.JArJDS
import myJs.Utils._

import scala.scalajs.js.Dynamic.{global => g}
import myJs.myPkg.jquery.$
import myJs.myPkg.{ColumnOptions, TableOptions, TreeGridOptions}
import myJs.tool.Tool
import myJs.user.data.DataManage
import myJs.user.soft.Anno
import org.scalajs.dom.ext.Ajax

import scala.collection.immutable.SeqMap
import scala.scalajs.js
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
import scalatags.Text.all._
import myJs.Implicits._
import shared.Pojo.MetDataKind
import shared.VarTool
import myJs.tool.Tool._

import scala.scalajs.js.JSConverters._
import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._

/**
 * Created by yz on 11/8/2020
 */
@JSExportTopLevel("MetSelectTab")
object MetSelectTab {

  val tabId = "metData"
  val tableId = "table"

  lazy val operateColumn = js.Array(
    ColumnOptions.field("operate").title(messages("operations")).formatter(operateFmt).filterControl("clear")
  )

  def operateFmt: js.Function = {
    (v: js.Any, row: js.Dictionary[js.Any]) =>
      val folder = MetDataKind.showDirName

      val selectStr = button(`class` := "btn  green btn-xs", title := messages("select"), `type` := "button",
        `class` := "myFileSelectButton", dataFolder := s"${folder}", dataFileName := s"${row("fileName").toString}",
        messages("select")
      )

      val rs = List(selectStr)
      rs.mkString("&nbsp;")
  }

  def tbFmt(columnName: String): js.Function = (v: js.Any, row: js.Dictionary[js.Any]) => columnName match {
    case "fileName" => {
      val url = g.jsRoutes.controllers.MatrixFileDataController.detailBefore().url.toString
      a(href := s"${url}?id=${row("id")}", target := "_blank", s"${v.toString}")
    }
    case "size" => Tool.getFileSize(v)
    case "tags" => Tool.tagMap.getOrElse(v.toString, v.toString)
    case _ => v
  }

  def onPostBody: js.Function = () => {
    val tableJq = $(s"#${tabId} #${tableId}")
    val options = tableJq.bootstrapTable("getOptions").toJDJAn
    val columnsOp = options.get("columns")
    columnsOp.foreach { columns =>
      val finalColumns = columns.asInstanceOf[js.Array[js.Array[js.Any]]]
      val visible = finalColumns(0)(1).toJDJAn("visible").toB
      if (visible) {
        def onChange: js.Function = () => {
          tableJq.bootstrapTable("resetView")
        }

        val treeGridOptions = TreeGridOptions.treeColumn(0).onChange(onChange)
        tableJq.treegrid(treeGridOptions)
      }
    }
  }

  def initTable = {
    FileModal.initFilterContent(tabId)
    val map = SeqMap("fileName" -> messages("fileName"), "tags" -> messages("tag"),
      "comment" -> messages("comment"), "size" -> messages("size"),
      "uploadTime" -> messages("uploadModifyTime"))
    val columnNames = map.keyList
    val columns = columnNames.map { columnName =>
      val title = map.getOrElse(columnName, columnName)
      val fmt = tbFmt(columnName)
      val basicOptions = ColumnOptions.field(columnName).title(title).sortable(true).formatter(fmt)
      columnName match {
        case x if List("fileName").contains(x) => basicOptions.
          sortable(false).operateable(true)
        case _ => basicOptions
      }
    }.concat(operateColumn)
    val options = TableOptions.columns(columns.toJSArray).searchOnButton(false).filterControl(false).idField("id").
      parentIdField("pId").treeShowField("fileName").treeEnable(true).rootParentId("0").onPostBody(onPostBody).
      locale(Tool.getBTLanguage)
    $(s"#${tabId} #${tableId}").bootstrapTable(options)
    //    Tool.dateInit
  }

  def tableDataF = {
    val url = g.jsRoutes.controllers.MatrixFileDataController.getAll().url.toString
    Ajax.get(url = s"${url.noCache}", headers = Map("Content-Type" -> "application/json")).map { xhr =>
      xhr.responseText.toJArJDJAn.toMyJDS
    }
  }

  @JSExport("refreshTable")
  def refreshTable(f: JArJDS => js.Any = (myData) => ()) = {
    val queryMap = Tool.getQueryMap(tabId)
    println(queryMap)
    tableDataF.map { data =>
      val sortData = DataManage.sortExec(data, queryMap)

      def loopFilter(sortData: JArJDS) = {

        val filterColumns = queryMap.removedAll(List("sort", "order")).filter(_._2.map(_.trim).nonEmpty).keyList

        def loop(acc: JArJDS, elems: List[String]): JArJDS = {
          elems match {
            case Nil => acc
            case y :: ys =>
              val searchV = queryMap(y)
              val trueSearchV = searchV.head
              val fieldName = y.split("\\.")(0)
              val name = y.split("\\.")(1)
              val curFilterData = {
                fieldName match {
                  case "size" => val (minSize, maxSize) = trueSearchV match {
                    case "0KB-100KB" => (0, 100 * 1024)
                    case "100KB-1MB" => (100 * 1024, 1 * 1024 * 1024)
                    case "1MB-10MB" => (1 * 1024 * 1024, 10 * 1024 * 1024)
                  }
                    acc.filter { row =>
                      val size = row(fieldName).toInt
                      size <= maxSize && size >= minSize
                    }
                  case "tags" => acc.filter { row =>
                    Tool.tagMap(row(fieldName)).contains(trueSearchV)
                  }
                  case x if DataManage.timeFieldNames.contains(x) => acc.filter { row =>
                    val dbDate = row(fieldName)
                    if (name == "startTime") {
                      Tool.timeBefore(trueSearchV, dbDate)
                    } else {
                      Tool.timeAfter(trueSearchV, dbDate)
                    }
                  }
                  case _ => acc.filter { row =>
                    row(fieldName).contains(trueSearchV)
                  }
                }
              }
              loop(curFilterData, ys)
          }
        }

        loop(sortData, filterColumns)
      }

      val filterData = loopFilter(sortData)
      $(s"#${tabId} #${tableId}").bootstrapTable("load", filterData)
      f(data)
    }
  }


}
